package com.freeLearning.boot.course.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.freeLearning.boot.common.annotation.Log;
import com.freeLearning.boot.common.enums.AuditStatusEnum;
import com.freeLearning.boot.common.enums.LogModuleEnum;
import com.freeLearning.boot.common.result.Result;
import com.freeLearning.boot.core.security.util.SecurityUtils;
import com.freeLearning.boot.course.mapper.CourseReviewAuditHistoryMapper;
import com.freeLearning.boot.course.model.entity.CourseReview;
import com.freeLearning.boot.course.model.entity.CourseReviewAuditHistory;
import com.freeLearning.boot.course.model.entity.CourseReviewLike;
import com.freeLearning.boot.course.model.query.CourseReviewPageQuery;
import com.freeLearning.boot.course.service.CourseInfoService;
import com.freeLearning.boot.course.service.CourseReviewLikeService;
import com.freeLearning.boot.course.service.CourseReviewService;
import com.freeLearning.boot.shared.mail.service.MailService;
import com.freeLearning.boot.shared.websocket.controller.WebsocketController;
import com.freeLearning.boot.shared.websocket.model.ChatMessage;
import com.freeLearning.boot.system.enums.MessageEnum;
import com.freeLearning.boot.system.model.dto.NoticeDTO;
import com.freeLearning.boot.system.model.entity.Message;
import com.freeLearning.boot.system.model.entity.UserRole;
import com.freeLearning.boot.system.service.MessageService;
import com.freeLearning.boot.system.service.UserRoleService;
import com.freeLearning.boot.system.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

@Tag(name = "24.课程评论")
@RequestMapping("/api/v1/course/review")
@RestController
@RequiredArgsConstructor
public class CourseReviewController {

    private final CourseReviewService courseReviewService;
    private final CourseReviewLikeService courseReviewLikeService;
    private final MessageService messageService;
    private final UserRoleService userRoleService;
    private final CourseReviewAuditHistoryMapper courseReviewAuditHistoryMapper;

    @Operation(summary = "分页查询课程评论")
    @PostMapping("/page")
    public Result<IPage<CourseReview>> page(@RequestBody CourseReviewPageQuery courseReviewPageQuery) {
        return Result.success(courseReviewService.pageQuery(courseReviewPageQuery));
    }

    @Operation(summary = "新增课程评论")
    @PostMapping("/add")
    public Result<Boolean> add(@RequestBody CourseReview courseReview) {
        courseReview.setReviewTime(LocalDateTime.now());
        sendReviewAuditMessage(courseReview, true);
        courseReview.setAuditInfo("审核中！");
        boolean save = courseReviewService.save(courseReview);
        CourseReviewAuditHistory courseReviewAuditHistory = CourseReviewAuditHistory.builder()
                .reviewId(courseReview.getId())
                .status(AuditStatusEnum.WAIT_AUDIT.getValue())
                .opinion("新增课程评论初审")
                .auditorId(SecurityUtils.getUserId())
                .auditorName(SecurityUtils.getNickName())
                .auditTime(LocalDateTime.now())
                .build();
        courseReviewAuditHistoryMapper.insert(courseReviewAuditHistory);
        return Result.success(save);
    }

    @Operation(summary = "删除课程评论")
    @DeleteMapping("/delete/{id}")
    @Log(value = "删除课程评论", module = LogModuleEnum.REVIEW)
    public Result<Boolean> delete(@PathVariable Long id) {
        return Result.success(courseReviewService.removeById(id));
    }

    @Operation(summary = "更新课程评论")
    @PutMapping("/update")
    public Result<Boolean> update(@RequestBody CourseReview courseReview) {
        courseReview.setReviewTime(LocalDateTime.now());
        courseReview.setStatus(AuditStatusEnum.WAIT_AUDIT.getValue());
        sendReviewAuditMessage(courseReview, false);
        courseReview.setAuditInfo("审核中！");
        CourseReviewAuditHistory courseReviewAuditHistory = CourseReviewAuditHistory.builder()
                .reviewId(courseReview.getId())
                .status(AuditStatusEnum.WAIT_AUDIT.getValue())
                .opinion("评价信息发生变化")
                .auditorId(SecurityUtils.getUserId())
                .auditorName(SecurityUtils.getNickName())
                .auditTime(LocalDateTime.now())
                .build();
        courseReviewAuditHistoryMapper.insert(courseReviewAuditHistory);
        return Result.success(courseReviewService.updateById(courseReview));
    }

    @Operation(summary = "审核课程评论")
    @PutMapping("/audit")
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> audit(@RequestBody CourseReview courseReview) {
        Long userId = SecurityUtils.getUserId();
        if (Objects.equals(courseReview.getStatus(), AuditStatusEnum.AUDIT_PASS.getValue())) {
            Message message = Message.builder()
                    .title("课程《" + courseReview.getCourseName() + "》收到一条新的评论")
                    .content("用户:" + courseReview.getNickName() + "评论了您的课程《" + courseReview.getCourseName() + "》;")
                    .type(MessageEnum.REVIEW.getValue())
                    .publisherId(courseReview.getUserId())
                    .publishTime(LocalDateTime.now())
                    .createBy(userId)
                    .other(JSONUtil.toJsonStr(courseReview))
                    .acceptId(courseReview.getConsultantId())
                    .build();
            messageService.sendMessage(message);
            courseReview.setAuditInfo("审核通过！");
            Message userMessage = Message.builder()
                    .title("评价通过")
                    .content("您在课程《" + courseReview.getCourseName() + "》的评论已经通过")
                    .type(MessageEnum.REVIEW_AUDIT_PASS.getValue())
                    .publisherId(userId)
                    .publishTime(LocalDateTime.now())
                    .createBy(userId)
                    .other(JSONUtil.toJsonStr(courseReview))
                    .acceptId(courseReview.getUserId())
                    .build();
            messageService.sendMessage(userMessage);
        } else {
            Message message = Message.builder()
                    .title("评价未通过")
                    .content("您在课程《" + courseReview.getCourseName() + "》的评论未通过审核，原因：" + courseReview.getAuditInfo())
                    .type(MessageEnum.REVIEW_AUDIT_NOT_PASS.getValue())
                    .publisherId(userId)
                    .publishTime(LocalDateTime.now())
                    .createBy(userId)
                    .other(JSONUtil.toJsonStr(courseReview))
                    .acceptId(courseReview.getUserId())
                    .build();
            messageService.sendMessage(message);
        }
        CourseReviewAuditHistory courseReviewAuditHistory = CourseReviewAuditHistory.builder()
                .reviewId(courseReview.getId())
                .status(courseReview.getStatus())
                .opinion(courseReview.getAuditInfo())
                .auditorId(SecurityUtils.getUserId())
                .auditorName(SecurityUtils.getNickName())
                .auditTime(LocalDateTime.now())
                .build();
        courseReviewAuditHistoryMapper.insert(courseReviewAuditHistory);
        return Result.success(courseReviewService.updateById(courseReview));
    }

    @Operation(summary = "点赞课程评论")
    @PostMapping("/like")
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> like(@RequestBody CourseReviewLike courseReviewLike) {
        Long userId = SecurityUtils.getUserId();
        CourseReviewLike one = courseReviewLikeService.getOne(new LambdaUpdateWrapper<CourseReviewLike>()
                .eq(CourseReviewLike::getReviewId, courseReviewLike.getReviewId())
                .eq(CourseReviewLike::getUserId, userId)
        );
        CourseReview courseReview = courseReviewService.getById(courseReviewLike.getReviewId());
        Integer likeCount = courseReview.getLikeCount();
        if (one == null) {
            courseReviewService.update(new LambdaUpdateWrapper<CourseReview>()
                    .eq(CourseReview::getId, courseReviewLike.getReviewId())
                    .set(CourseReview::getLikeCount, likeCount + 1)
            );
            Message message = Message.builder()
                    .title("您收到一条点赞！")
                    .content(SecurityUtils.getNickName() + "点赞了您在课程《" + courseReview.getCourseName() + "》下的评论;")
                    .type(MessageEnum.LIKE.getValue())
                    .publisherId(userId)
                    .publishTime(LocalDateTime.now())
                    .createBy(userId)
                    .acceptId(courseReview.getUserId())
                    .build();
            messageService.sendMessage(message);
            return Result.success(courseReviewLikeService.save(courseReviewLike));
        }
        courseReviewService.update(new LambdaUpdateWrapper<CourseReview>()
                .eq(CourseReview::getId, courseReviewLike.getReviewId())
                .set(CourseReview::getLikeCount, likeCount - 1)
        );
        return Result.success(courseReviewLikeService.removeById(one.getId()));
    }

    public void sendReviewAuditMessage(CourseReview courseReview, Boolean isAdd) {
        List<UserRole> adminList = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getRoleId, 2));
        StringBuilder content = new StringBuilder();
        content
                .append("用户：")
                .append(courseReview.getNickName());

        if (isAdd) {
            content.append("评论了课程《")
                    .append(courseReview.getCourseName())
                    .append("》,请尽快审核！");
        } else {
            content.append(",修改了在课程《")
                    .append(courseReview.getCourseName())
                    .append("》的评论，请尽快审核！");
        }
        adminList.forEach(item -> {
            Message message = Message.builder()
                    .title("有新的评论需要审核")
                    .content(content.toString())
                    .type(MessageEnum.REVIEW_AUDIT.getValue())
                    .publisherId(courseReview.getUserId())
                    .publishTime(LocalDateTime.now())
                    .createBy(courseReview.getUserId())
                    .acceptId(item.getUserId())
                    .build();
            messageService.sendMessage(message);
        });
    }

    @Operation(summary = "评价审核历史记录")
    @GetMapping("/audit/history/{id}")
    public Result<List<CourseReviewAuditHistory>> auditHistory(@PathVariable Long id) {
        List<CourseReviewAuditHistory> list = courseReviewAuditHistoryMapper.selectList(
                new LambdaQueryWrapper<CourseReviewAuditHistory>()
                        .eq(CourseReviewAuditHistory::getReviewId, id)
                        .orderByDesc(CourseReviewAuditHistory::getAuditTime));
        return Result.success(list);
    }
}
